{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Implementing an RNN in TensorFlow\n",
    "----------------------------------\n",
    "\n",
    "This script implements an RNN in TensorFlow to predict spam/ham from texts.\n",
    "\n",
    "We start by loading the necessary libraries and initializing a computation graph in TensorFlow."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import re\n",
    "import io\n",
    "import requests\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import tensorflow as tf\n",
    "from zipfile import ZipFile\n",
    "from tensorflow.python.framework import ops\n",
    "ops.reset_default_graph()\n",
    "\n",
    "# Start a graph\n",
    "sess = tf.Session()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we set the parameters for the RNN model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set RNN parameters\n",
    "epochs = 50\n",
    "batch_size = 250\n",
    "max_sequence_length = 25\n",
    "rnn_size = 10\n",
    "embedding_size = 50\n",
    "min_word_frequency = 10\n",
    "learning_rate = 0.0005\n",
    "dropout_keep_prob = tf.placeholder(tf.float32)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We download and save the data next.  First we check if we have saved it before and load it locally, if not, we load it from the internet (UCI machine learning data repository)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Download or open data\n",
    "data_dir = 'temp'\n",
    "data_file = 'text_data.txt'\n",
    "if not os.path.exists(data_dir):\n",
    "    os.makedirs(data_dir)\n",
    "\n",
    "if not os.path.isfile(os.path.join(data_dir, data_file)):\n",
    "    zip_url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/00228/smsspamcollection.zip'\n",
    "    r = requests.get(zip_url)\n",
    "    z = ZipFile(io.BytesIO(r.content))\n",
    "    file = z.read('SMSSpamCollection')\n",
    "    # Format Data\n",
    "    text_data = file.decode()\n",
    "    text_data = text_data.encode('ascii', errors='ignore')\n",
    "    text_data = text_data.decode().split('\\n')\n",
    "\n",
    "    # Save data to text file\n",
    "    with open(os.path.join(data_dir, data_file), 'w') as file_conn:\n",
    "        for text in text_data:\n",
    "            file_conn.write(\"{}\\n\".format(text))\n",
    "else:\n",
    "    # Open data from text file\n",
    "    text_data = []\n",
    "    with open(os.path.join(data_dir, data_file), 'r') as file_conn:\n",
    "        for row in file_conn:\n",
    "            text_data.append(row)\n",
    "    text_data = text_data[:-1]\n",
    "\n",
    "text_data = [x.split('\\t') for x in text_data if len(x) >= 1]\n",
    "[text_data_target, text_data_train] = [list(x) for x in zip(*text_data)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we process the texts and turn them into numeric representations (words --> indices)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a text cleaning function\n",
    "def clean_text(text_string):\n",
    "    text_string = re.sub(r'([^\\s\\w]|_|[0-9])+', '', text_string)\n",
    "    text_string = \" \".join(text_string.split())\n",
    "    text_string = text_string.lower()\n",
    "    return text_string\n",
    "\n",
    "\n",
    "# Clean texts\n",
    "text_data_train = [clean_text(x) for x in text_data_train]\n",
    "\n",
    "# Change texts into numeric vectors\n",
    "vocab_processor = tf.contrib.learn.preprocessing.VocabularyProcessor(max_sequence_length,\n",
    "                                                                     min_frequency=min_word_frequency)\n",
    "text_processed = np.array(list(vocab_processor.fit_transform(text_data_train)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Note: there will be a WARNING:... use tensorflow/transform or tf.data.  Ignore this for now- there is an issue with getting tensorflow/transform to work. Hopefully this will be fixed soon and the code here will be updated.\n",
    "\n",
    "Now we shuffle and split the texts into train/tests (80% training, 20% testing)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Vocabulary Size: 933\n",
      "80-20 Train Test split: 4459 -- 1115\n"
     ]
    }
   ],
   "source": [
    "# Shuffle and split data\n",
    "text_processed = np.array(text_processed)\n",
    "text_data_target = np.array([1 if x == 'ham' else 0 for x in text_data_target])\n",
    "shuffled_ix = np.random.permutation(np.arange(len(text_data_target)))\n",
    "x_shuffled = text_processed[shuffled_ix]\n",
    "y_shuffled = text_data_target[shuffled_ix]\n",
    "\n",
    "# Split train/test set\n",
    "ix_cutoff = int(len(y_shuffled)*0.80)\n",
    "x_train, x_test = x_shuffled[:ix_cutoff], x_shuffled[ix_cutoff:]\n",
    "y_train, y_test = y_shuffled[:ix_cutoff], y_shuffled[ix_cutoff:]\n",
    "vocab_size = len(vocab_processor.vocabulary_)\n",
    "print(\"Vocabulary Size: {:d}\".format(vocab_size))\n",
    "print(\"80-20 Train Test split: {:d} -- {:d}\".format(len(y_train), len(y_test)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we can define our RNN model.  We create the placeholders for the data, word embedding matrices (and embedding lookups), and define the rest of the model.\n",
    "\n",
    "The rest of the RNN model will create a dynamic RNN cell (regular RNN type), which will vary the number of RNNs needed for variable input length (different amount of words for input texts), and then output into a fully connected logistic layer to predict spam or ham as output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create placeholders\n",
    "x_data = tf.placeholder(tf.int32, [None, max_sequence_length])\n",
    "y_output = tf.placeholder(tf.int32, [None])\n",
    "\n",
    "# Create embedding\n",
    "embedding_mat = tf.Variable(tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0))\n",
    "embedding_output = tf.nn.embedding_lookup(embedding_mat, x_data)\n",
    "\n",
    "# Define the RNN cell\n",
    "# tensorflow change >= 1.0, rnn is put into tensorflow.contrib directory. Prior version not test.\n",
    "if tf.__version__[0] >= '1':\n",
    "    cell = tf.contrib.rnn.BasicRNNCell(num_units=rnn_size)\n",
    "else:\n",
    "    cell = tf.nn.rnn_cell.BasicRNNCell(num_units=rnn_size)\n",
    "\n",
    "output, state = tf.nn.dynamic_rnn(cell, embedding_output, dtype=tf.float32)\n",
    "output = tf.nn.dropout(output, dropout_keep_prob)\n",
    "\n",
    "# Get output of RNN sequence\n",
    "output = tf.transpose(output, [1, 0, 2])\n",
    "last = tf.gather(output, int(output.get_shape()[0]) - 1)\n",
    "\n",
    "weight = tf.Variable(tf.truncated_normal([rnn_size, 2], stddev=0.1))\n",
    "bias = tf.Variable(tf.constant(0.1, shape=[2]))\n",
    "logits_out = tf.matmul(last, weight) + bias"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we declare the loss function (softmax cross entropy), an accuracy function, and optimization function (RMSProp)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/nick/.local/lib/python3.6/site-packages/tensorflow/python/ops/gradients_impl.py:108: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.\n",
      "  \"Converting sparse IndexedSlices to a dense Tensor of unknown shape. \"\n"
     ]
    }
   ],
   "source": [
    "# Loss function\n",
    "losses = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=logits_out, labels=y_output)\n",
    "loss = tf.reduce_mean(losses)\n",
    "\n",
    "accuracy = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(logits_out, 1), tf.cast(y_output, tf.int64)), tf.float32))\n",
    "\n",
    "optimizer = tf.train.RMSPropOptimizer(learning_rate)\n",
    "train_step = optimizer.minimize(loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> You may ignore the warning, as the texts are small and our batch size is only 100.  If you increase the batch size and/or have longer sequences of texts, this model may consume too much memory.\n",
    "\n",
    "Next we initialize the variables in the computational graph."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "init = tf.global_variables_initializer()\n",
    "sess.run(init)\n",
    "\n",
    "train_loss = []\n",
    "test_loss = []\n",
    "train_accuracy = []\n",
    "test_accuracy = []"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can start our training!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch: 1, Test Loss: 0.73, Test Acc: 0.18\n",
      "Epoch: 2, Test Loss: 0.69, Test Acc: 0.18\n",
      "Epoch: 3, Test Loss: 0.64, Test Acc: 0.83\n",
      "Epoch: 4, Test Loss: 0.59, Test Acc: 0.84\n",
      "Epoch: 5, Test Loss: 0.53, Test Acc: 0.84\n",
      "Epoch: 6, Test Loss: 0.48, Test Acc: 0.84\n",
      "Epoch: 7, Test Loss: 0.45, Test Acc: 0.84\n",
      "Epoch: 8, Test Loss: 0.43, Test Acc: 0.85\n",
      "Epoch: 9, Test Loss: 0.42, Test Acc: 0.85\n",
      "Epoch: 10, Test Loss: 0.41, Test Acc: 0.85\n",
      "Epoch: 11, Test Loss: 0.4, Test Acc: 0.85\n",
      "Epoch: 12, Test Loss: 0.4, Test Acc: 0.85\n",
      "Epoch: 13, Test Loss: 0.4, Test Acc: 0.86\n",
      "Epoch: 14, Test Loss: 0.4, Test Acc: 0.86\n",
      "Epoch: 15, Test Loss: 0.39, Test Acc: 0.86\n",
      "Epoch: 16, Test Loss: 0.39, Test Acc: 0.86\n",
      "Epoch: 17, Test Loss: 0.39, Test Acc: 0.87\n",
      "Epoch: 18, Test Loss: 0.39, Test Acc: 0.87\n",
      "Epoch: 19, Test Loss: 0.38, Test Acc: 0.87\n",
      "Epoch: 20, Test Loss: 0.38, Test Acc: 0.87\n",
      "Epoch: 21, Test Loss: 0.38, Test Acc: 0.87\n",
      "Epoch: 22, Test Loss: 0.37, Test Acc: 0.87\n",
      "Epoch: 23, Test Loss: 0.37, Test Acc: 0.87\n",
      "Epoch: 24, Test Loss: 0.36, Test Acc: 0.87\n",
      "Epoch: 25, Test Loss: 0.35, Test Acc: 0.88\n",
      "Epoch: 26, Test Loss: 0.33, Test Acc: 0.88\n",
      "Epoch: 27, Test Loss: 0.28, Test Acc: 0.89\n",
      "Epoch: 28, Test Loss: 0.25, Test Acc: 0.91\n",
      "Epoch: 29, Test Loss: 0.22, Test Acc: 0.94\n",
      "Epoch: 30, Test Loss: 0.22, Test Acc: 0.93\n",
      "Epoch: 31, Test Loss: 0.19, Test Acc: 0.95\n",
      "Epoch: 32, Test Loss: 0.18, Test Acc: 0.95\n",
      "Epoch: 33, Test Loss: 0.18, Test Acc: 0.95\n",
      "Epoch: 34, Test Loss: 0.16, Test Acc: 0.96\n",
      "Epoch: 35, Test Loss: 0.15, Test Acc: 0.96\n",
      "Epoch: 36, Test Loss: 0.15, Test Acc: 0.96\n",
      "Epoch: 37, Test Loss: 0.14, Test Acc: 0.96\n",
      "Epoch: 38, Test Loss: 0.14, Test Acc: 0.97\n",
      "Epoch: 39, Test Loss: 0.13, Test Acc: 0.97\n",
      "Epoch: 40, Test Loss: 0.13, Test Acc: 0.96\n",
      "Epoch: 41, Test Loss: 0.12, Test Acc: 0.96\n",
      "Epoch: 42, Test Loss: 0.12, Test Acc: 0.97\n",
      "Epoch: 43, Test Loss: 0.11, Test Acc: 0.97\n",
      "Epoch: 44, Test Loss: 0.1, Test Acc: 0.97\n",
      "Epoch: 45, Test Loss: 0.1, Test Acc: 0.97\n",
      "Epoch: 46, Test Loss: 0.11, Test Acc: 0.96\n",
      "Epoch: 47, Test Loss: 0.097, Test Acc: 0.98\n",
      "Epoch: 48, Test Loss: 0.096, Test Acc: 0.98\n",
      "Epoch: 49, Test Loss: 0.091, Test Acc: 0.98\n",
      "Epoch: 50, Test Loss: 0.091, Test Acc: 0.97\n"
     ]
    }
   ],
   "source": [
    "# Start training\n",
    "for epoch in range(epochs):\n",
    "\n",
    "    # Shuffle training data\n",
    "    shuffled_ix = np.random.permutation(np.arange(len(x_train)))\n",
    "    x_train = x_train[shuffled_ix]\n",
    "    y_train = y_train[shuffled_ix]\n",
    "    num_batches = int(len(x_train)/batch_size) + 1\n",
    "    # TO DO CALCULATE GENERATIONS ExACTLY\n",
    "    for i in range(num_batches):\n",
    "        # Select train data\n",
    "        min_ix = i * batch_size\n",
    "        max_ix = np.min([len(x_train), ((i+1) * batch_size)])\n",
    "        x_train_batch = x_train[min_ix:max_ix]\n",
    "        y_train_batch = y_train[min_ix:max_ix]\n",
    "        \n",
    "        # Run train step\n",
    "        train_dict = {x_data: x_train_batch, y_output: y_train_batch, dropout_keep_prob:0.5}\n",
    "        sess.run(train_step, feed_dict=train_dict)\n",
    "        \n",
    "    # Run loss and accuracy for training\n",
    "    temp_train_loss, temp_train_acc = sess.run([loss, accuracy], feed_dict=train_dict)\n",
    "    train_loss.append(temp_train_loss)\n",
    "    train_accuracy.append(temp_train_acc)\n",
    "    \n",
    "    # Run Eval Step\n",
    "    test_dict = {x_data: x_test, y_output: y_test, dropout_keep_prob:1.0}\n",
    "    temp_test_loss, temp_test_acc = sess.run([loss, accuracy], feed_dict=test_dict)\n",
    "    test_loss.append(temp_test_loss)\n",
    "    test_accuracy.append(temp_test_acc)\n",
    "    print('Epoch: {}, Test Loss: {:.2}, Test Acc: {:.2}'.format(epoch+1, temp_test_loss, temp_test_acc))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is matplotlib code to plot the loss and accuracy over the training generations for both the train and test sets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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t6emwpQpsGOHc0SQc79B48bQtSvcfTece64znHWrVnDWWfnWLCI8++yzRdpPY0qbDXNRBn3//ffMnj2bevXq0aVLF6677roSXX9qaiq33347X3/9NeB8wAYFBTFixAj+/e9/A1C7dm2+/vprrrjiinzX8/vvv3PppZeSlZXFkiVLaN68eeEbV4WDB2HXLti/n2lvv81P06fzypNPUu3oUafLJT09z5qTfvuNc+rUgQMH2LN+PdWOHaPEn9AbFERmtWqkpKcT1qABVcLCnOcbR0ScfEj9RRdBk9xXVxtTttnYR2XI7t27mTBhAkOGDOG8884LaC1HjhyhT58+LFiwgNjYWIYNG0aVKlUQEbKyssjOzmbXrl1cf/31bNu2jRkzZnDttdeetp5jx47RtWtXtm/fzk8//UTHjh2dD/Ndu5xp5868p127nG/kealaFerWdR4w7yVblaSkJI5lZtKySxeqNmhAUloah4KDqdeqFfVbt6ZKw4bOe+vVOznVru18s891JLBn61aeGDOGJatW0bdfP0a/+CKh9epBaCipmZlEtW1LjRo1iIuL85wnMaa88zUUrPuolLz88suEhITw9NNPF9jut99+IyMjgzZt2iAipKWlMWbMGDp16kS/fv3OuI4hQ4awaNEipkyZwoABA055LTg4mODdu2k+fz7Lb72Vr6dN48Jp02D6dOcD9cQJzwdrjdRUvjl0iLPq16fWLbfAkSOQ142F1as736qbNHG+aef8fvbZEBGB1q3Ltf36kVazJj+tWAG5up5Ulf79+vH5558z+9tvadO9O4jQGGjsyw5Xrw41a56yqGHHjrzdqxejR49m3LhxzFy3jlmzZhF51lm8/OKLbN26le+//94CwVRKdqTgZ+vXr2fevHm89957nDhxwnMTV34eeOABT19/SEgIWVlZXHzxxezcuZOEhATCwsLOqJ6NGzeyefNmevbs6SxIS4OFC2HOHGdau/bUN4SGoqGhpAUFEVKnDhoaSnpwMNXPOsv5Rh8a6kxhYc4Hfc6Hfs5Ur95pH/S5xcbGMnLkSJYuXcqFF154ymuvv/46Dz74IC+99BL/93//d0b7npfZs2fz6quvMmPGDJKSkoiKiqJv375MnTq1xLdlTCD5eqQQ8KuJijqVt6uPHnnkEa1SpYo+88wzCujatWsLbN+mTRvt3bv3Kct+/vlnBfRv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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "# Plot loss over time\n",
    "epoch_seq = np.arange(1, epochs+1)\n",
    "plt.plot(epoch_seq, train_loss, 'k--', label='Train Set')\n",
    "plt.plot(epoch_seq, test_loss, 'r-', label='Test Set')\n",
    "plt.title('Softmax Loss')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Softmax Loss')\n",
    "plt.legend(loc='upper left')\n",
    "plt.show()\n",
    "\n",
    "# Plot accuracy over time\n",
    "plt.plot(epoch_seq, train_accuracy, 'k--', label='Train Set')\n",
    "plt.plot(epoch_seq, test_accuracy, 'r-', label='Test Set')\n",
    "plt.title('Test Accuracy')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Accuracy')\n",
    "plt.legend(loc='lower right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Evaluating New Texts\n",
    "\n",
    "Here, we show how to use our trained model to evaluate new texts (which may or may not be spam/ham)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_texts = ['Hi, please respond 1111 asap to claim your change to win now!',\n",
    "                'Hey what are you doing for dinner tonight?',\n",
    "                'New offer, show this text for 50% off of our inagural sale!',\n",
    "                'Can you take the dog to the vet tomorrow?',\n",
    "                'Congratulations! You have been randomly selected to receive account credit!']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we clean our sample texts."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['hi please respond asap to claim your change to win now', 'hey what are you doing for dinner tonight', 'new offer show this text for off of our inagural sale', 'can you take the dog to the vet tomorrow', 'congratulations you have been randomly selected to receive account credit']\n"
     ]
    }
   ],
   "source": [
    "clean_texts = [clean_text(text) for text in sample_texts]\n",
    "print(clean_texts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we transform each text as a sequence of words into a sequence of vocabulary indices."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 93  99   0   0   1 114  13 524   1 178  21   0   0   0   0   0   0   0\n",
      "    0   0   0   0   0   0   0]\n",
      " [121  52  20   3 151  12 332 208   0   0   0   0   0   0   0   0   0   0\n",
      "    0   0   0   0   0   0   0]\n",
      " [ 92 376 483  39  69  12 203  15  86   0   0   0   0   0   0   0   0   0\n",
      "    0   0   0   0   0   0   0]\n",
      " [ 28   3 104   5   0   1   5   0 143   0   0   0   0   0   0   0   0   0\n",
      "    0   0   0   0   0   0   0]\n",
      " [701   3  17  98   0 420   1 318 301 738   0   0   0   0   0   0   0   0\n",
      "    0   0   0   0   0   0   0]]\n"
     ]
    }
   ],
   "source": [
    "processed_texts = np.array(list(vocab_processor.transform(clean_texts)))\n",
    "print(processed_texts)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can run each of the texts through our model and get the output logits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.89795506 0.10204492]\n",
      " [0.00980581 0.99019414]\n",
      " [0.8838587  0.11614131]\n",
      " [0.00980508 0.990195  ]\n",
      " [0.88657707 0.11342289]]\n"
     ]
    }
   ],
   "source": [
    "# Remember to wrap the resulting logits in a softmax to get probabilities\n",
    "eval_feed_dict = {x_data: processed_texts, dropout_keep_prob: 1.0}\n",
    "model_results = sess.run(tf.nn.softmax(logits_out), feed_dict=eval_feed_dict)\n",
    "\n",
    "print(model_results)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now print results"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Text: Hi, please respond 1111 asap to claim your change to win now!, \n",
      "Prediction: spam\n",
      "\n",
      "Text: Hey what are you doing for dinner tonight?, \n",
      "Prediction: ham\n",
      "\n",
      "Text: New offer, show this text for 50% off of our inagural sale!, \n",
      "Prediction: spam\n",
      "\n",
      "Text: Can you take the dog to the vet tomorrow?, \n",
      "Prediction: ham\n",
      "\n",
      "Text: Congratulations! You have been randomly selected to receive account credit!, \n",
      "Prediction: spam\n",
      "\n"
     ]
    }
   ],
   "source": [
    "categories = ['spam', 'ham']\n",
    "\n",
    "for ix, result in enumerate(model_results):\n",
    "    prediction = categories[np.argmax(result)]\n",
    "    \n",
    "    print('Text: {}, \\nPrediction: {}\\n'.format(sample_texts[ix], prediction))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
